/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bhatni.mockprocessor.macro;

import com.bhatni.mockprocessor.Message;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Viren
 */
public abstract class BaseMacro {

    private static final char macroStart = '{';
    private static final char macroEnd = '}';
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void setValue(String value);

    public abstract String getResolvedValue(Message in);

    public void applyTo(Message in, Message out) {
        String resolvedValue = getResolvedValue(in);
        String parsedContent = out.getBody().toString();

        if (resolvedValue != null) {
            out.setBody(replaceString(parsedContent, macroStart + getName() + macroEnd, resolvedValue));
        } 
    }

    /**
     *  Replace all occurrences of a string in the input string with a new string.
     *
     *@param  inputString  the input String
     *@param  oldString    the String to replace
     *@param  newString    the String to replace with
     *@return              the input String with the old String replaced by the new String
     */
    public String replaceString(String inputString, String oldString, String newString) {
        if (inputString == null || oldString == null) {
            return inputString;
        }

        if (newString == null) {
            newString = "";
        }

        StringBuffer buf = new StringBuffer();
        int start = 0;
        int end = 0;
        int inc = oldString.length();

        while ((end = inputString.indexOf(oldString, start)) != -1) {
            buf.append(inputString.substring(start, end));
            buf.append(newString);
            start = end + inc;
        }

        buf.append(inputString.substring(start));

        return buf.toString();
    }

    static public BaseMacro createMacro(String macroType, String macroName, String value) {
        try {
            String macroFullClassName = BaseMacro.class.getPackage().getName() + "." + macroType;
            Class<?> macroClass = BaseMacro.class.getClassLoader().loadClass(macroFullClassName);
            BaseMacro macroInstance = (BaseMacro) macroClass.getConstructor().newInstance();
            macroInstance.setName(macroName);
            macroInstance.setValue(value);
            return macroInstance;
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(BaseMacro.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(BaseMacro.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(BaseMacro.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(BaseMacro.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(BaseMacro.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(BaseMacro.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(BaseMacro.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;

    }

}
